// ============================================================================
// FileName: SIPSwitchPersistor.cs
//
// Description:
// Retrieves and persists sipswitch objects from a persistent data store such as a relational
// database or XML file. Examples of the type of objects are SIP accounts, a list of supported
// domains etc.
//
// Author(s):
// Aaron Clauson
//
// History:
// 14 Sep 2008	Aaron Clauson	Created.
//
// License: 
// This software is licensed under the BSD License http://www.opensource.org/licenses/bsd-license.php
//
// Copyright (c) 2008 Aaron Clauson (aaronc@blueface.ie), Blue Face Ltd, Dublin, Ireland (www.blueface.ie)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that 
// the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
// disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Blue Face Ltd. 
// nor the names of its contributors may be used to endorse or promote products derived from this software without specific 
// prior written permission. 
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.
// ============================================================================

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BlueFace.Sys;
using BlueFace.VoIP.Net.SIP;
using BlueFace.VoIP.SIPServer;
using BlueFace.VoIP.SIPServerCores.StatefulProxy;
using log4net;

namespace BlueFace.VoIP.SIP.StatefulProxy
{
    public delegate void SIPDomainsUpdatedDelegate(SIPDomains sipDomains);
    public delegate void SIPProvidersUpdatedDelegate();
    public delegate void SIPDialPlansUpdatedDelegate();

    public class SIPSwitchPersistorFactory
    {
        public static SIPSwitchPersistor CreateSIPSwitchPersistor(StorageTypes storageType, string storageConnectionStr)
        {
            if (storageType == StorageTypes.Postgresql)
            {
                return new SIPSwitchSQLPersistor(storageType, storageConnectionStr);
            }
            else if (storageType == StorageTypes.XML)
            {
                return new SIPSwitchXMLPersistor(storageType, storageConnectionStr);
            }
            else
            {
                throw new ApplicationException(storageType + " is not supported as a SIPSwitch persistence option.");
            }
        }
    }

    public abstract class SIPSwitchPersistor
    {
        public abstract event SIPDomainsUpdatedDelegate DomainsUpdated;
        public abstract event SIPProvidersUpdatedDelegate SIProvidersUpdated;
        public abstract event SIPDialPlansUpdatedDelegate DialplansUpdated;

        public SIPSwitchPersistor(StorageTypes storageType, string storageConnectionStr)
        { }

        public abstract bool DoesSIPAccountExist(string user, string canonicalDomain);
        
        public abstract List<SIPAddressBinding> GetSIPAccountBindings(string user, string canonicalDomain);

        public abstract bool ProxyMonitorAuthenticate(string username, string password);

        public abstract bool HasDialPlanBeenUpdated(string username, string domain);

        public abstract string LoadDialPlanSource(string username);

        public abstract string GetUserEmailAddress(string username);

        public abstract List<SIPProvider> GetSIPProvidersForUser(string username);

        public abstract string GetExtensionOwner(string user, string domain);

        public abstract string GetSIPAccountOwner(string user, string domain);

        public abstract SIPAccount LoadSIPAccount(string username, string domain);

        public abstract SIPDomains LoadSIPDomains();

        public abstract List<UserRegistration> Load3rdPartyRegistrations();

        public abstract SIPRegistrarRecord LoadPersistedRegistrarRecord(SIPParameterlessURI addressOfRecord);
    }
}
